from fastapi import APIRouter, UploadFile, File, HTTPException, BackgroundTasks
from typing import List, Dict, Any, Optional
from pathlib import Path
from ..services.dicom_service_optimized import dicom_service
from ..services.file_service import file_service
from ..utils.config import settings
from ..auth.routes import router as auth_router
from ..api.patient_data_routes import router as patient_data_router
from ..api.patient_data_routes_orm import router as patient_data_orm_router
from ..api.high_concurrency_routes import router as high_concurrency_router
import asyncio
import logging

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# 创建路由器
router = APIRouter()

# 存储上传任务的状态
upload_tasks = {}

async def process_dicom_file(file_path: str, filename: str):
    """后台处理DICOM文件转换为JPEG"""
    try:
        # 更新任务状态为处理中
        upload_tasks[filename] = {"status": "processing", "progress": 0}
        
        # 转换为JPEG（这是一个耗时操作）
        jpeg_result = dicom_service.extract_dicom_frames(Path(file_path))
        
        # 更新任务状态为完成
        upload_tasks[filename] = {
            "status": "completed", 
            "progress": 100,
            "result": jpeg_result
        }
        
        logger.info(f"DICOM文件 {filename} 处理完成")
    except Exception as e:
        # 更新任务状态为失败
        upload_tasks[filename] = {
            "status": "failed", 
            "progress": 0,
            "error": str(e)
        }
        logger.error(f"DICOM文件 {filename} 处理失败: {str(e)}")

@router.post("/upload", response_model=Dict[str, Any])
async def upload_dicom(file: UploadFile = File(...), background_tasks: BackgroundTasks = None):
    """异步上传DICOM文件"""
    from pathlib import Path
    
    if not dicom_service.validate_dicom_file(file.filename):
        raise HTTPException(status_code=400, detail="只允许上传DICOM文件(.dcm)")
    
    # 保存文件
    file_path = settings.DICOM_STORAGE / file.filename
    file_service.save_uploaded_file(file.file, file_path)
    
    # 初始化任务状态
    upload_tasks[file.filename] = {"status": "uploaded", "progress": 0}
    
    # 添加后台任务处理DICOM转换
    if background_tasks:
        background_tasks.add_task(process_dicom_file, str(file_path), file.filename)
    
    # 读取元数据
    try:
        metadata = dicom_service.read_metadata(file_path)
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    
    return {
        "filename": file.filename,
        "path": str(file_path),
        "metadata": metadata,
        "status": "uploaded",
        "message": "文件已上传，正在后台处理DICOM转换",
        "task_id": file.filename  # 使用文件名作为任务ID
    }

@router.get("/dicom-files", response_model=List[Dict[str, Any]])
async def list_dicom_files():
    """列出所有上传的DICOM文件，并确保每个文件都有对应的JPEG图像"""
    files = file_service.list_dicom_files()
    
    # 检查并确保每个DICOM文件都有对应的JPEG图像
    for file_info in files:
        dicom_path = file_info.get("path")
        if dicom_path:
            # 确保为现有DICOM文件生成JPEG
            from pathlib import Path
            jpeg_result = dicom_service.extract_dicom_frames(Path(dicom_path))
            if jpeg_result and jpeg_result.get("success"):
                # 如果成功提取帧，返回完整的帧信息
                file_info["dcm_info"] = jpeg_result
                file_info["dcm_available"] = True
                # 如果需要保持向后兼容，也可以设置 jpeg_path 为第一帧的路径
                if jpeg_result.get("extracted_files"):
                    file_info["dcm_path"] = jpeg_result["extracted_files"][0]
            else:
                file_info["dcm_available"] = False
                file_info["dcm_error"] = jpeg_result.get("message") if jpeg_result else "未知错误"
    
    return files

@router.get("/dicom-file")
async def get_dicom_file(filename: str = None):
    """根据文件名获取DICOM文件信息，或列出所有上传的DICOM文件，并确保每个文件都有对应的JPEG图像"""
    if filename:
        # 根据文件名查找特定文件
        file_path = settings.DICOM_STORAGE / filename
        if not file_service.file_exists(file_path):
            raise HTTPException(status_code=404, detail="文件不存在")
        
        try:
            # 读取文件元数据
            metadata = dicom_service.read_metadata(file_path)
            
            # 获取帧数信息
            frame_count = 0
            try:
                from pydicom import dcmread
                ds = dcmread(file_path)
                frame_count = getattr(ds, 'NumberOfFrames', 1)
            except Exception:
                pass  # 如果无法读取帧数，保持默认值0
            
            file_info = {
                "filename": filename,
                "size": file_path.stat().st_size,
                "metadata": metadata,
                "frame_count": str(frame_count)  # 转换为字符串以保持一致性
            }
            
            # 确保为现有DICOM文件生成JPEG
            jpeg_result = dicom_service.extract_dicom_frames(file_path)
            if jpeg_result and jpeg_result.get("success"):
                # 如果成功提取帧，返回完整的帧信息
                file_info["dcm_info"] = jpeg_result
                file_info["dcm_available"] = True
                # 如果需要保持向后兼容，也可以设置 jpeg_path 为第一帧的路径
                if jpeg_result.get("extracted_files"):
                    file_info["dcm_path"] = jpeg_result["extracted_files"][0]
            else:
                file_info["dcm_available"] = False
                file_info["dcm_error"] = jpeg_result.get("message") if jpeg_result else "未知错误"
                
            return file_info
        except Exception as e:
            raise HTTPException(status_code=500, detail=f"读取文件信息失败: {str(e)}")
    

@router.get("/download/{filename}")
async def download_dicom(filename: str):
    """下载DICOM文件"""
    file_path = settings.DICOM_STORAGE / filename
    if not file_service.file_exists(file_path):
        raise HTTPException(status_code=404, detail="文件不存在")
    
    # 确保有对应的JPEG图像
    jpeg_result = dicom_service.extract_dicom_frames(file_path)
    
    return {
        "file_path": str(file_path),
        "filename": filename,
        "jpeg_result": jpeg_result if jpeg_result else None,
        "jpeg_available": jpeg_result is not None and jpeg_result.get("success", False)
    }

@router.delete("/delete/{filename}")
async def delete_dicom(filename: str):
    """删除DICOM文件"""
    file_path = settings.DICOM_STORAGE / filename
    if not file_service.file_exists(file_path):
        raise HTTPException(status_code=404, detail="文件不存在")
    
    if file_service.delete_file(file_path):
        return {"status": "success", "message": f"文件 {filename} 已删除"}
    else:
        raise HTTPException(status_code=500, detail="文件删除失败")

@router.get("/search")
async def search_dicom(patient_id: Optional[str] = None, modality: Optional[str] = None):
    """根据条件搜索DICOM文件"""
    return dicom_service.search_dicom_files(patient_id, modality)

@router.get("/extract-dicom/{filename}")
async def extract_dicom_frames(filename: str):
    """拆解DICOM文件，提取所有帧并保存为单独的JPEG文件"""
    file_path = settings.DICOM_STORAGE / filename
    if not file_service.file_exists(file_path):
        raise HTTPException(status_code=404, detail="文件不存在")
    
    if not dicom_service.validate_dicom_file(filename):
        raise HTTPException(status_code=400, detail="只支持DICOM文件(.dcm)")
    
    # 调用拆解功能
    result = dicom_service.extract_dicom_frames(file_path)
    
    if result.get("success"):
        return result
    else:
        raise HTTPException(status_code=500, detail=result.get("message", "拆解失败"))

@router.get("/dicom-metadata/{filename}")
async def get_dicom_metadata(filename: str):
    """获取指定DICOM文件的元数据"""
    file_path = settings.DICOM_STORAGE / filename
    if not file_service.file_exists(file_path):
        raise HTTPException(status_code=404, detail="文件不存在")
    
    try:
        metadata = dicom_service.read_metadata(file_path)
        return metadata
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"读取元数据失败: {str(e)}")

@router.get("/dicom-frames/{filename}")
async def get_dicom_frames(filename: str):
    """获取指定DICOM文件的帧列表"""
    file_path = settings.DICOM_STORAGE / filename
    if not file_service.file_exists(file_path):
        raise HTTPException(status_code=404, detail="文件不存在")
    
    # 确保DICOM文件已处理并生成帧图像
    result = dicom_service.extract_dicom_frames(file_path)
    
    if result.get("success"):
        # 构造帧列表信息
        frames_info = []
        for i, frame_path in enumerate(result.get("extracted_files", [])):
            frames_info.append({
                "index": i,
                "path": frame_path,
                "thumbnail": frame_path.replace('/dicom-img/', '/dicom-img/thumbnails/')
            })
        
        return frames_info
    else:
        raise HTTPException(status_code=500, detail=result.get("message", "获取帧列表失败"))

@router.get("/upload/status/{filename}")
async def get_upload_status(filename: str):
    """获取上传任务状态"""
    if filename in upload_tasks:
        return upload_tasks[filename]
    else:
        raise HTTPException(status_code=404, detail="任务不存在")

@router.get("/")
async def root():
    """根路径"""
    return {"message": "DICOM Server 运行中"}

# 包含鉴权路由
router.include_router(auth_router, prefix="/auth", tags=["auth"])

# 包含患者数据路由
router.include_router(patient_data_router)

# 包含ORM患者数据路由
router.include_router(patient_data_orm_router)

# 包含高并发接口路由
router.include_router(high_concurrency_router)
